package com.gblfy.es7jdvue.service;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Arrays;

@Service
public class ESa {


    @Autowired
    private RestHighLevelClient restHighLevelClient;


    //匹配搜索（会拆词）
    public void matchQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "三三").operator(Operator.OR);
        doSearch(searchRequest,searchSourceBuilder,matchQueryBuilder);
    }
    //短语搜索
    public void matchPhraseQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("title", "JAVA开发").slop(1);
        doSearch(searchRequest,searchSourceBuilder,matchPhraseQueryBuilder);
    }

    //queryString搜索
    public void queryString() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

//        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("不");
        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("不").field("slogan");
        doSearch(searchRequest,searchSourceBuilder,queryStringQueryBuilder);
    }

    //多字段匹配搜索
    public void multiMatchQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery("明","alias","slogan");
        doSearch(searchRequest,searchSourceBuilder,multiMatchQuery);
    }













    //词项前缀搜索(prefix query)
    public void prefixQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        PrefixQueryBuilder prefixQuery = QueryBuilders.prefixQuery("title","资深");
        doSearch(searchRequest,searchSourceBuilder,prefixQuery);
    }

    //通配符搜索(wildcard query)
    public void wildcardQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        WildcardQueryBuilder wildcardQuery = QueryBuilders.wildcardQuery("name","张*三").boost(2);
        doSearch(searchRequest,searchSourceBuilder,wildcardQuery);
    }

    //正则搜索
    public void regexpQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        RegexpQueryBuilder regexpQueryBuilder = QueryBuilders.regexpQuery("title","高级.*");
        doSearch(searchRequest,searchSourceBuilder,regexpQueryBuilder);
    }

    // 模糊搜索(fuzzy query)
    public void fuzzyQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("title","高级");
        doSearch(searchRequest,searchSourceBuilder,fuzzyQueryBuilder);
    }

    // ids搜索(id集合查询)(ids query)
    public void idsQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        IdsQueryBuilder idsQueryBuilder = QueryBuilders.idsQuery().addIds("t1UY3nsB1bu3ZtXKDENc");
        doSearch(searchRequest,searchSourceBuilder,idsQueryBuilder);
    }

    //复合查询
    public void boolQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchTitleQueryBuilder = QueryBuilders.matchQuery("title", "高级");
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").from(25,false).to(30);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(matchTitleQueryBuilder).mustNot(rangeQueryBuilder);
        doSearch(searchRequest,searchSourceBuilder,boolQueryBuilder);
    }

    //排序
    public void sortQuery() throws IOException {
        //  搜索请求对象
        SearchRequest searchRequest = new SearchRequest("yuangong");
        //  搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchTitleQueryBuilder = QueryBuilders.matchQuery("title", "高级");
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").from(25, false).to(30);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(matchTitleQueryBuilder).mustNot(rangeQueryBuilder);
        doSearch(searchRequest, searchSourceBuilder, boolQueryBuilder);
    }


    public void doSearch(SearchRequest searchRequest,
                         SearchSourceBuilder searchSourceBuilder,
                         QueryBuilder query) throws IOException {
        //  sort,text字段不能用于排序
        FieldSortBuilder age = SortBuilders.fieldSort("age").order(SortOrder.ASC);
        searchSourceBuilder.query(query).sort(age);
        //  向搜索请求对象中设置搜索源
        searchRequest.source(searchSourceBuilder);
        //  执行搜索,向ES发起http请求
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //  搜索结果
        SearchHits hits = searchResponse.getHits();
        System.out.println(Arrays.toString(hits.getHits()));
    }
}
